/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.comut.crud.bo;

import com.comut.crud.pojo.FindAndSet;
import com.comut.crud.dao.GroupDao;
import com.comut.crud.ejb.interfaces.IGroupAction;
import com.comut.crud.pojo.group.Group;
import com.comut.crud.pojo.user.User;
import com.comut.crud.util.ParseJson;
import com.comut.lib.error.ErrorCodes;
import com.comut.lib.exception.JSONMalFormedException;
import com.comut.lib.exception.ObjectFoundException;
import com.comut.lib.exception.ObjectNotFoundException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import org.apache.log4j.Logger;

/**
 *
 * @author asantos
 */
public class GroupHandler implements IGroupAction {

    private static Logger _logger = Logger.getLogger(GroupHandler.class.getName());
    private static final String _tagsSeparator = ResourceBundle.getBundle("application").getString("tagsSeparator");
    private Connection _connection;
    private GroupDao groupDao;

    public GroupHandler(Connection connection) {
        this._connection = connection;
        groupDao = new GroupDao(_connection);

    }

    public Group insertGroup(Group group) throws ObjectFoundException {
        if (group.isValid()) {
            int id = groupDao.createGroup(group);

            if (group.getTags() != null && !group.getTags().isEmpty()) {
            }

            Group toRet = new Group();
            toRet.setId(id);
            _logger.info(toRet.toString());
            return toRet;
        } else {
            throw new JSONMalFormedException("The mandatory attributes are not in json.", ErrorCodes.JSON_MAL_FORMED);
        }
    }

    public void deleteGroup(Group group) throws ObjectNotFoundException {
        _logger.info(group.toString());
        groupDao.deleteGroup(group.getId());
    }

    public void updateGroup(String group) throws ObjectNotFoundException {
        _logger.info(group.toString());
        //check if the BasicDBObject is well formed
        FindAndSet fas = ParseJson.getInstance().buildSQLQueryForGroup(group, ParseJson.getInstance().getGroupFind(), ParseJson.getInstance().getGroupUpdate(),
                ParseJson.getInstance().getGroupFindStr(), ParseJson.getInstance().getGroupUpdateStr());

        _logger.info("FindAndSet completed");
        //update the group
        groupDao.updateGroup(fas);
        _logger.info("groupDao.updateGroup completed");
        //update tags
        if (fas.getGroupTags() != null ) {
            groupDao.deleteGroupTags(fas.getId());
            if(!fas.getGroupTags().isEmpty()){
                for (String tagId : fas.getGroupTags()) {
                    groupDao.insertGroupTags(fas.getId(), Integer.parseInt(tagId));
                }
            }
            
            _logger.info("updateGroupTags completed");
            // get the name of the tags 
            String tags = getTagsNames(fas.getId());
            
            //get the emails of users associated with this group
            List<String> emails = getUserEmailsFromGroup(fas.getId());
            
            //update mailChimp
            if(!emails.isEmpty()){
                for(String email: emails){
                    User user = new User();
                    user.setTags(tags);
                    NotificationHandler.notifyAboutUsersUpdate(email, user);   
                }                
            }
        }

        if(!fas.getUpdate().isEmpty() && !fas.getFind().isEmpty()){
            NotificationHandler.notifyAboutGroups();
            NotificationHandler.notifyTOMAboutGroups(NotificationHandler.TomCRUDUpdate, fas.getId());
            _logger.info("notifyAboutGroups CEP and TOM completed");
        }
    }

    public Group getGroup(Group group) throws ObjectNotFoundException {

        ResultSet rs = null;
        Group toRet = new Group();
        try {
            rs = groupDao.getGroup(group.getId());
            if (rs.next()) {
                toRet.setId(group.getId());
                toRet.setAlias(rs.getString("alias"));
            }
        } catch (SQLException ex) {
            _logger.error(ex);
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException ignore) {
                }
            }
        }

        _logger.info(toRet.toString());
        return toRet;
    }

    /**
     * get the tags names of the group and put it in a String using separator _tagsSeparator
     * @param groupId
     * @return 
     */
    public String getTagsNames(int groupId) {
        ResultSet rs = null;
        String toRet = "";
        try {
            rs = groupDao.getTagsNames(groupId);
            while (rs.next()) {
                toRet += (rs.getString(1)) + _tagsSeparator;
            }
        } catch (SQLException ex) {
            _logger.error(ex);
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException ignore) {
                }
            }
        }

        return toRet;
    }
    
    
    /**
     * get a List with the user emails associated with the group id_group
     * @param id_group
     * @return 
     */
    private List<String> getUserEmailsFromGroup(int id_group) {
        
        List<String> emailsList = new ArrayList();
        ResultSet rs = null;
        try {
            rs = groupDao.getUsersFromGroup(id_group);
            while (rs.next()) {
                emailsList.add(rs.getString("email"));
            }
        } catch (SQLException ex) {
            _logger.error("getUserEmailsFromGroup: ",ex);
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException ignore) {
                }
            }
        }
        
        return emailsList;
    }
    
    
    /**
     * get a List with the user(name, email) associated with the group id_group
     * @param id_group
     * @return 
     */
    public List<User> getUsersFromGroupToMailChimp(int id_group) {
        
        List<User> userList = new ArrayList();
        ResultSet rs = null;
        try {
            rs = groupDao.getUsersFromGroup(id_group);
            while (rs.next()) {
                User u = new User();
                u.setEmail(rs.getString("email"));
                u.setName(rs.getString("name"));
                userList.add(u);
            }
        } catch (SQLException ex) {
            _logger.error("getUserFromGroupToMailChimp: ",ex);
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException ignore) {
                }
            }
        }
        
        return userList;
    }
    
    /**
     * get all IDs of the groups
     * @return
     * @throws ObjectNotFoundException 
     */
    public List<Integer> getGroups() {

        ResultSet rs = null;
        List<Integer> toRet = new ArrayList<Integer>();
        try {
            rs = groupDao.getGroups();
            while (rs.next()) {
                toRet.add(rs.getInt(1));
            }
        } catch (SQLException ex) {
            _logger.error(ex);
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException ignore) {
                }
            }
        }

        return toRet;
    }
}
